﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.DirectX.Direct3D;
using Microsoft.DirectX;
using System.Drawing;
using System.IO;

namespace ESpace
{
    class EDX
    {
        public static Device dvc = null;
        public static bool bWBuf = false;
        public static Matrix vMtr;
        public static Matrix pMtr;

        public delegate void DeviceReset(object sender, EventArgs e);

        public static Device CreareDevice(System.Windows.Forms.Control Window,  bool WBuf,DeviceReset OnDeviceReset, bool FullScreen)
        {
            return CreareDevice(Window,WBuf, OnDeviceReset, FullScreen, 800, 600);
        }

        public static Device CreareDevice(System.Windows.Forms.Control Window, bool WBuf, DeviceReset OnDeviceReset, bool FullScreen, int w, int h)
        {
            // Start up full screen
            Format current = Manager.Adapters[0].CurrentDisplayMode.Format;

            // параметры (представление данных на экране)
            PresentParameters presentParams = new PresentParameters();

            if (FullScreen)
            {
                if (Manager.CheckDeviceType(0, DeviceType.Hardware, current, current, false))
                {
                    // Perfect, this is valid
                    presentParams.Windowed = false;
                    presentParams.BackBufferFormat = current;
                    presentParams.BackBufferWidth = w;
                    presentParams.BackBufferHeight = h;
                }
                else
                {
                    presentParams.Windowed = true;
                }
            }
            else
            {
                // рисовать в окне
                presentParams.Windowed = true;
            }
            // режим работы - сбрасывает содержимое буфера если он не готов к представлению
            presentParams.SwapEffect = SwapEffect.Discard;
            // использования буфера глубины
            if (WBuf)
            {
                presentParams.EnableAutoDepthStencil = true;
                presentParams.AutoDepthStencilFormat = DepthFormat.D16;
            }

            // сохраняем номер адаптера
            int adapterOrdinal = Manager.Adapters.Default.Adapter;

            // устанавливаем флаги обработки
            CreateFlags flags = CreateFlags.SoftwareVertexProcessing;
            // Смотрим, поддерживает ли устройство аппаратную поддержку вершин
            Caps caps = Manager.GetDeviceCaps(adapterOrdinal, DeviceType.Hardware);
            if (caps.DeviceCaps.SupportsHardwareTransformAndLight)
            {
                // если да, то меняем на HardwareVertexProcessing
                flags = CreateFlags.HardwareVertexProcessing;
            }
            // Do we support a pure device?
            if (caps.DeviceCaps.SupportsPureDevice) 
                flags |= CreateFlags.PureDevice;

            // создание устройства
            if (!FullScreen) dvc = new Device(adapterOrdinal, DeviceType.Hardware, Window, flags, presentParams);
            else dvc = new Device(adapterOrdinal, DeviceType.Hardware, Window, flags, presentParams);

            // установка функции, вызавающийся по событию сброса устройства
            dvc.DeviceReset += new EventHandler(OnDeviceReset);

            bWBuf = WBuf;
            return dvc;
        }

        public static Device CreareDevice(System.Windows.Forms.Control Window)
        {
            // Create our device

            PresentParameters presentParams = new PresentParameters();
            presentParams.Windowed = true;
            presentParams.SwapEffect = SwapEffect.Discard;
            presentParams.AutoDepthStencilFormat = DepthFormat.D16;
            presentParams.EnableAutoDepthStencil = true;

            dvc = new Device(0, DeviceType.Hardware, Window, CreateFlags.SoftwareVertexProcessing, presentParams);

            dvc.Transform.Projection = Matrix.PerspectiveFovLH(
                (float)Math.PI / 4, Window.Width / Window.Height, 1.0f, 100.0f);

            dvc.Transform.View = Matrix.LookAtLH(new Vector3(0, 0, -9.0f),
                new Vector3(), new Vector3(0, 1, 0));
            return dvc;
        }

        public static void ClearDraw(Color clr)
        {
            // очищаем окно с заливкой цветом
            if (EDX.bWBuf)
                dvc.Clear(ClearFlags.Target | ClearFlags.ZBuffer, clr, 1.0f, 0);
            else
                dvc.Clear(ClearFlags.Target, clr, 1.0f, 0);
        }
      
        // установка камеры
        public static void SetupCamera(Vector3 pos, Vector3 targ, float aspectRatio, float angleVis, float minVis, float maxVis, bool RenderAllSides, bool Light)
        {
            // рендерить все стороны (можно поставить, чтобы рендерил только внешнюю (стоит по умолчанию))
            if (RenderAllSides) dvc.RenderState.CullMode = Cull.None;

            // установка камеры (угол видимости, соотношение сторон, минимальный обзор, максимальный обзор)
            pMtr = Matrix.PerspectiveFovLH(ToRadian(angleVis), aspectRatio, minVis, maxVis);
            dvc.Transform.Projection = pMtr;

            // (положение камеры, положение таргета, поворот камеры вокруг оси)
            // таргет - вторая точка, для проведения линии от камеры. линия указывает куда смотреть, поворот камеры (обычно 0,1,0)
            vMtr = Matrix.LookAtLH(pos, targ, new Vector3(0, 1, 0));
            dvc.Transform.View = vMtr;
            // освещение на сцене
            dvc.RenderState.Lighting = Light;
        }

        public static void SetupCameraDefault(Vector3 pos, Vector3 targ, float minVis, float maxVis, bool Light)
        {
            SetupCamera(pos, targ, 4f / 3f, 45, minVis, maxVis, false, Light);
        }

        public static Vector3 GetNorm(Vector3 a, Vector3 b, Vector3 c)
        {
            Vector3 n = new Vector3();
            n.X = (b.Y - a.Y) * (c.Z - a.Z) - (b.Z - a.Z) * (c.Y - a.Y);
            n.Y = (c.X - a.X) * (b.Z - a.Z) - (b.X - a.X) * (c.Z - a.Z);
            n.Z = (b.X - a.X) * (c.Y - a.Y) - (c.X - a.X) * (b.Y - a.Y);

            Vector3 n1 = new Vector3();
            n1.X = a.Y * (b.Z - c.Z) + b.Y * (c.Z - a.Z) + c.Y * (a.Z - b.Z);
            n1.Y = a.Z * (b.X - c.X) + b.Z * (c.X - a.X) + c.Z * (a.X - b.X);
            n1.Z = a.X * (b.Y - c.Y) + b.X * (c.Y - a.Y) + c.X * (a.Y - b.Y);

            n.X = n1.X / (float)Math.Sqrt(n1.X * n1.X + n1.Y * n1.Y + n1.Z * n1.Z);
            n.Y = n1.Y / (float)Math.Sqrt(n1.X * n1.X + n1.Y * n1.Y + n1.Z * n1.Z);
            n.Z = n1.Z / (float)Math.Sqrt(n1.X * n1.X + n1.Y * n1.Y + n1.Z * n1.Z);

            return n;
        }

        public static void AddLightPoint(int num, Vector3 pos)
        { 
            AddLightPoint(num, pos, 0, 200);
        }

        public static void AddLightPoint(int num, Vector3 pos, float Attenuation, float Range)
        {
            dvc.Lights[num].Type = LightType.Point; // тип освещения
            dvc.Lights[num].Position = pos; // положение
            dvc.Lights[num].Diffuse = Color.White; // цвет
            dvc.Lights[num].Attenuation0 = Attenuation; // затухание
            dvc.Lights[num].Range = Range; // максимальное расстояние распространения света
            dvc.Lights[num].Attenuation1 = 0;
            dvc.Lights[num].Attenuation2 = 0.0005f;
            dvc.Lights[num].Enabled = true;
        }

        public static void AddLightPoint(int num, Vector3 pos, float Attenuation, float Range, Color clr)
        {
            dvc.Lights[num].Type = LightType.Point; // тип освещения
            dvc.Lights[num].Position = pos; // положение
            dvc.Lights[num].Diffuse = clr; // цвет
            dvc.Lights[num].Attenuation0 = Attenuation; // затухание
            dvc.Lights[num].Range = Range; // максимальное расстояние распространения света
            dvc.Lights[num].Enabled = true;
        }

        public static void AddLightDirectional(int num, Vector3 napr)
        {
            dvc.Lights[num].Type = LightType.Directional; // тип освещения
            dvc.Lights[num].Direction = napr; // направление
            dvc.Lights[num].Diffuse = Color.White; // цвет
            dvc.Lights[num].Attenuation0 = 1; // затухание
            dvc.Lights[num].Range = 10000; // максимальное расстояние распространения света
            dvc.Lights[num].Enabled = true;

        }

        public static float ToRadian(double Grad)
        {
            return (float)(Grad * Math.PI / 180.0);
        }

        public static float ToGrad(float Radian)
        {
            return Radian / ((float)Math.PI / 180f);
        }

        public class ExMesh
        {
            public Mesh m = null;
            public Material[] mt = null;
            public Texture[] tx = null;
            public GraphicsStream adj; // массив смежности

            public ExMesh Clone()
            {
                ExMesh msh = new ExMesh();
                msh.m = m.Clone(m.Options.Value, m.VertexFormat, dvc);
                msh.mt = (Material[])mt.Clone();
                msh.tx = (Texture[])tx.Clone();
                msh.adj = adj;
                return msh;
            }
        }
        
        /// <summary>
        /// Загрузка меша
        /// </summary>
        /// <param name="fPathMesh">путь к файлу меша</param>
        /// <param name="dPathTextures">путь к папке с текстурами для меша</param>
        /// <param name="bAdj">нужно ли выцеплять массив смежности. Если нет, массив смежности будет = null </param>
        /// <returns></returns>
        public static ExMesh LoadMesh(String fPathMesh, String dPathTextures, bool bAdj)
        {
            ExMesh msh = new ExMesh();
            ExtendedMaterial[] mtrl;

            // загрузка меша.
            // путь к файлу, флаги опций, устройство, ссылка на массив материалов
            if(bAdj) msh.m = Mesh.FromFile(fPathMesh, MeshFlags.Managed, dvc, out msh.adj, out mtrl);
            else msh.m = Mesh.FromFile(fPathMesh, MeshFlags.Managed, dvc, out mtrl);
            msh.adj = null;

            // Если есть какие-либо материалы
            if ((mtrl != null) && (mtrl.Length > 0))
            {
                // создаем массив материалов и текстур к мешу
                msh.mt = new Material[mtrl.Length];
                msh.tx = new Texture[mtrl.Length];

                // пробегаемся по всем материалам
                for (int i = 0; i < mtrl.Length; i++)
                {
                   // присваиваем материал
                    msh.mt[i] = mtrl[i].Material3D;
                    // если есть текстура, присваиваем текстуру
                    if ((mtrl[i].TextureFilename != null) && (mtrl[i].TextureFilename != string.Empty))
                    {

                        if (File.Exists(dPathTextures + "\\" + mtrl[i].TextureFilename)) 
                            msh.tx[i] = TextureLoader.FromFile(dvc, dPathTextures + "\\" + mtrl[i].TextureFilename);
                       
                    }
                }
            }
            return msh;
        }

        public static void DrawMesh(Mesh msh, Material[] mt, Texture[] tx)
        {
            if (mt.Length > 0)
            {
                // рисуем мешь со всеми материалами
                for (int i = 0; i < mt.Length; i++)
                {
                    if (mt != null)
                        if (i < mt.Length) dvc.Material = mt[i];
                    dvc.SetTexture(0, null);
                    if (tx != null)
                        if (i < tx.Length) dvc.SetTexture(0, tx[i]);
                    msh.DrawSubset(i);
                }
            }
            else
                msh.DrawSubset(0);
        }

        public static void DrawMesh(ExMesh msh)
        {
            DrawMesh(msh.m, msh.mt, msh.tx);
        }

        /// <summary>
        /// Ambient - фоновый свет. (цвет материала (в тени))
        /// Diffuse - рассеиваемый свет. (цвет материала при попадании света (цвет рассеимого света))
        /// Specular - отражаемый свет.
        /// Emissive - собственное свечение объекта.
        /// Power - резкость отражений. 
        /// </summary>
        public static Material CreateMaterial(Color Ambient, Color Diffuse, Color Specular, Color Emissive, float Power)
        {
            Material mtrl = new Material();
            // цвет материала (в тени)
            mtrl.Ambient = Ambient;
            // цвет материала при попадании света (цвет рассеимого света)
            mtrl.Diffuse = Diffuse;
            mtrl.Specular = Specular;
            mtrl.Emissive = Emissive;
            mtrl.SpecularSharpness = Power;
            return mtrl;
        }

        static Microsoft.DirectX.Direct3D.Font fnt = null; 
        public static Color FontColor = Color.Thistle;
        public static void DrawString(String s, int x, int y)
        {
            if(fnt==null)fnt = new Microsoft.DirectX.Direct3D.Font(dvc, new System.Drawing.Font("Arial", 10,FontStyle.Bold));
            fnt.DrawText(null, s, x, y, FontColor);
        }

        //Преобразование 3D в 2D
       public static Vector2 Conv3DTo2D(Vector3 v, int w, int h)
        {
            Vector2 vpoint;

            Vector3 vtmp = Vector3.TransformCoordinate(v, vMtr);
            vtmp = Vector3.TransformCoordinate(vtmp, pMtr);
            vpoint.X = (int)((vtmp.X + 1) * w / 2);
            vpoint.Y = (int)((1 - vtmp.Y) * h / 2);
            return vpoint;
        }

       public enum StandAxis { X, Y, Z };
       public static Vector3 Conv2DTo3D(StandAxis standAxis, float mX, float mY, Matrix pMtr, Matrix vMtr)
        {
            Vector3 near = new Vector3(mX, mY, dvc.Viewport.MinZ);
            Vector3 far = new Vector3(mX, mY, dvc.Viewport.MaxZ);
            // Transform points to world space
            near = Vector3.Unproject(near, dvc.Viewport, pMtr, vMtr, Matrix.Identity);
            far = Vector3.Unproject(far, dvc.Viewport, pMtr, vMtr, Matrix.Identity);
            // Find Y Intercept
            Vector3 direction = far - near;
            if (far.Y < 0) // if your mouse ray ends below XZ Plane
            {
                float yFactor = -near.Y / direction.Y;
                float xFactor = -near.X / direction.X;
                float zFactor = -near.Z / direction.Z;
                Vector3 zeroWorldPoint = new Vector3();
                if (standAxis == StandAxis.X) zeroWorldPoint = near + direction * xFactor;
                if (standAxis == StandAxis.Y) zeroWorldPoint = near + direction * yFactor;// zeroWorldPoint.X and zeroWorldPoint.Z contain XZ Plane Intercept
                if (standAxis == StandAxis.Z) zeroWorldPoint = near + direction * zFactor;
                return zeroWorldPoint;
            }
            return direction;
        }

        public static Vector3 TargPos(Vector3 Pos, float AngX, float AngY)
        {
            return TargPos(Pos.X, Pos.Y, Pos.Z, AngX, AngY);
        }

        public static Vector3 TargPos(float x, float y, float z, float AngX, float AngY)
        {
            Vector3 tPos = new Vector3();
            tPos.X = (float)((Math.Sin(EDX.ToRadian(AngY))) * Math.PI * 2) + x;
            tPos.Z = (float)((Math.Cos(EDX.ToRadian(AngY))) * Math.PI * 2) + z;
            tPos.Y = -(float)((Math.Sin(EDX.ToRadian(AngX))) * Math.PI * 2) + y;
            tPos.Z = -(float)((Math.Cos(EDX.ToRadian(AngX))) * Math.PI * 2) + tPos.Z;
            return tPos;
        }

    }

    public class ECamera
    {
        public Matrix vMtr;
        Matrix vMtr0; // начальная матрица
        public Matrix pMtr;
        Device dvc;

        Vector3 pPos;

        float pAngleVis;
        float pAspectRatio;
        float MinVis;
        float MaxVis;

        public Vector3 Pos
        {
            get { return pPos; }
            set 
            {
                pPos = value;
                vMtr0 = Matrix.LookAtLH(pPos, new Vector3(pPos.X, pPos.Y, pPos.Z + 10), new Vector3(0, 10, 0));
                ResetAngCam();
            }
        }

        public float X
        {
            get { return Pos.X; }
            set
            {
                pPos.X = value;
                vMtr0 = Matrix.LookAtLH(pPos, new Vector3(pPos.X, pPos.Y, pPos.Z + 10), new Vector3(0, 1, 0));
                ResetAngCam();
            }
        }
        public float Y
        {
            get { return Pos.Y; }
            set
            {
                pPos.Y = value;
                vMtr0 = Matrix.LookAtLH(pPos, new Vector3(pPos.X, pPos.Y, pPos.Z + 10), new Vector3(0, 1, 0));
                ResetAngCam();
            }
        }
        public float Z
        {
            get { return Pos.Z; }
            set
            {
                pPos.Z = value;
                vMtr0 = Matrix.LookAtLH(pPos, new Vector3(pPos.X, pPos.Y, pPos.Z + 10), new Vector3(0, 1, 0));
                ResetAngCam();
            }
        }

        float pAngX = 0;
        float pAngY = 0;
        float pAngZ = 0;
        /// <summary>угол поворота по оси X</summary>
        public float AngX
        {
            get { return pAngX; }
            set
            {
                pAngX = value;
                ResetAngCam();
            }
        }

        /// <summary>угол поворота по оси Y</summary>
        public float AngY
        {
            get { return pAngY; }
            set
            {
                pAngY = value;
                ResetAngCam();
            }
        }

        /// <summary>угол поворота по оси Y</summary>
        public float AngZ
        {
            get { return pAngZ; }
            set
            {
                pAngZ = value;
                ResetAngCam();
            }
        }

        /// <summary>угол видимости (обычно 45 или 60 градусов)</summary>
        public float AngleVis
        {
            get { return pAngleVis; }
            set
            {
                if (value > 0 && value < 180)
                {
                    pAngleVis = value;
                    ResetCam();
                }
            }
        }

        /// <summary>соотношение сторон</summary>
        public float AspectRatio
        {
            get { return pAspectRatio; }
            set
            {
                pAspectRatio = value;
                ResetCam();
            }
        }

        public bool Lighting { get { return dvc.RenderState.Lighting; } set { dvc.RenderState.Lighting = value; } }

        public ECamera(Device dvc, Vector3 pos, float AngX, float AngY, float aspectRatio, float angleVis, float minVis, float maxVis)
        {
            this.dvc = dvc;
            pAngleVis = angleVis;
            pAspectRatio = aspectRatio;
            MinVis = minVis;
            MaxVis = maxVis;
            pPos = pos;

            ResetCam();

            // освещение на сцене
            dvc.RenderState.Lighting = true;
        }

        public void ResetCam()
        {
            // рендерить все стороны (можно поставить, чтобы рендерил только внешнюю (стоит по умолчанию))
            //if (RenderAllSides) dvc.RenderState.CullMode = Cull.None;

            // установка камеры (угол видимости, соотношение сторон, минимальный обзор, максимальный обзор)
            pMtr = Matrix.PerspectiveFovLH(EDX.ToRadian(pAngleVis), pAspectRatio, MinVis, MaxVis);
            dvc.Transform.Projection = pMtr;
            vMtr0 = Matrix.LookAtLH(pPos, new Vector3(pPos.X, pPos.Y, pPos.Z + 10), new Vector3(0, 1, 0));
            ResetAngCam();

        }

        void ResetAngCam()
        {
            //PosT = TargPos();
            vMtr = vMtr0 * Matrix.RotationY(EDX.ToRadian(360.0 - AngY)) * Matrix.RotationX(EDX.ToRadian(360.0 - AngX)) * Matrix.RotationZ(EDX.ToRadian(360.0 - AngZ));
            // (положение камеры, положение таргета, поворот камеры вокруг оси)
            dvc.Transform.View = vMtr;
        }

        //Преобразование 3D в 2D
        public Vector2 Conv3DTo2D(Vector3 v, int w, int h)
        {
            Vector2 vpoint;

            Vector3 vtmp = Vector3.TransformCoordinate(v, vMtr);
            vtmp = Vector3.TransformCoordinate(vtmp, pMtr);
            vpoint.X = (int)((vtmp.X + 1) * w / 2);
            vpoint.Y = (int)((1 - vtmp.Y) * h / 2);
            return vpoint;
        }

        public enum StandAxis { X, Y, Z };
        public Vector3 Conv2DTo3D(StandAxis standAxis, float mX, float mY)
        {
            Vector3 near = new Vector3(mX, mY, dvc.Viewport.MinZ);
            Vector3 far = new Vector3(mX, mY, dvc.Viewport.MaxZ);
            // Transform points to world space
            near = Vector3.Unproject(near, dvc.Viewport, pMtr, vMtr, Matrix.Identity);
            far = Vector3.Unproject(far, dvc.Viewport, pMtr, vMtr, Matrix.Identity);
            // Find Y Intercept
            Vector3 direction = far - near;
            if (far.Y < 0) // if your mouse ray ends below XZ Plane
            {
                float yFactor = -near.Y / direction.Y;
                float xFactor = -near.X / direction.X;
                float zFactor = -near.Z / direction.Z;
                Vector3 zeroWorldPoint = new Vector3();
                if (standAxis == StandAxis.X) zeroWorldPoint = near + direction * xFactor;
                if (standAxis == StandAxis.Y) zeroWorldPoint = near + direction * yFactor;// zeroWorldPoint.X and zeroWorldPoint.Z contain XZ Plane Intercept
                if (standAxis == StandAxis.Z) zeroWorldPoint = near + direction * zFactor;
                return zeroWorldPoint;
            }
            return direction;
        }

    }

    public class ESprite
    {
        // определяет точку, откуда рисовать спрайт
        // 0,0,0 - верхний-левый угол
        static readonly Vector3 Center = new Vector3(0, 0, 1);
        Sprite sprite;
        Texture tx;
        int pW;
        int pH;
        public int Width { get { return pW; } }
        public int Height { get { return pW; } }

        public void SetColor(Color clr)
        {
            SurfaceDescription s = tx.GetLevelDescription(0);
            uint[,] data = (uint[,])tx.LockRectangle(typeof(uint), 0,
                LockFlags.None, s.Width, s.Height);
            uint val = (uint)clr.ToArgb();
            for (int i = 0; i < s.Width; i++)
            {
                for (int j = 0; j < s.Height; j++)
                {
                    data[i, j] = val;
                }
            }
            tx.UnlockRectangle(0);

        }
        
        /*про текстуры - 
         * неважно какого размера ваш рисунок, размер текстури всегда 
         * равен степени двойки 32х32, 64х64, 128х128, 256х256... 
         * а рисунок растягивается под размер.*/
        public ESprite(Device dvc, String fPath)
        {
            // грузим текстуру
            tx = TextureLoader.FromFile(dvc, fPath);
            sprite = new Sprite(dvc);
            SurfaceDescription s = tx.GetLevelDescription(0);
            pW = s.Width;
            pH = s.Height;
        }

        public void Draw(float posX, float posY)
        {
            // начинаем рисовать спрайты, учитывая альфа канал
            sprite.Begin(SpriteFlags.AlphaBlend);
            sprite.Draw(tx, Center, new Vector3(posX, posY, 1), Color.White.ToArgb());
            // сообщаем, что мы заканчиваем рисовать спрайты
            sprite.End();
        }

        public void DrawR(int x, int y, int w, int h)
        {
            // начинаем рисовать спрайты, учитывая альфа канал
            sprite.Begin(SpriteFlags.AlphaBlend);
            sprite.Draw2D(tx, new Rectangle(0, 0, pW, pH), new Rectangle(x, y, w, h), new Point(0, 0), 0, new Point(x, y), Color.White);
            //sprite.Draw2D(tx, new Rectangle(0, 0, pW, pH), new SizeF(w, h), new Point(x, y), Color.White);
            // сообщаем, что мы заканчиваем рисовать спрайты
            sprite.End();
        }

    }

    public class ESpriteAnim
    {
        private static readonly Vector3 Center = new Vector3(0, 0, 0);
        Sprite sprite;
        List<Texture> tx = new List<Texture>();
        int pActFrame = 0;

        public int ActFrame
        {
            get { return pActFrame; }
            set { pActFrame = Math.Abs(value) % tx.Count; }
        }
        float pfps = 25;
        float elTimeCnt = 0;
        float elTimeFPS = 0.04f;
        public float fps
        {
            get { return pfps; }
            set
            {
                pfps = value;
                if (pfps <= 0) pfps = 0.000000001f;
                elTimeFPS = 1f / pfps;
            }
        }

        /// <summary>
        /// dPath - папка в которой хранятся картинки по кадрам
        /// кадры сортируются по имени. (кадр с самым маленьким именем будет самый первый)
        /// в папке не должно быть каких-либо других файлов, кроме кадров-картинок спрайта
        /// </summary>
        public ESpriteAnim(Device dvc, String dPath)
        {
            try
            {
                String[] f = System.IO.Directory.GetFiles(dPath);
                for (int i = 0; i < f.Length; i++)
                    tx.Add(TextureLoader.FromFile(dvc, f[i]));

            }
            catch { }
            sprite = new Sprite(dvc);
        }

        public void Draw(float posX, float posY, float elTime)
        {
            // начинаем рисовать спрайты, учитывая альфа канал
            sprite.Begin(SpriteFlags.AlphaBlend);
            sprite.Draw(tx[pActFrame], Center, new Vector3(posX, posY, 1), Color.White.ToArgb());
            // сообщаем, что мы заканчиваем рисовать спрайты
            sprite.End();
            if (elTimeCnt >= elTimeFPS)
            {
                elTimeCnt -= elTimeFPS;
                pActFrame++; if (pActFrame >= tx.Count) pActFrame = 0;
            }
            else elTimeCnt += elTime;
        }
        public void Draw(float posX, float posY, float elTime, int frame)
        {
            ActFrame = frame;
            Draw(posX, posY, elTime);
        }

    }
}
